package jym.tan.tmdb;

import jym.tan.tmdb.bean.AuthenticationRequest;
import jym.tan.tmdb.bean.Configuration;
import jym.tan.tmdb.bean.MovieInfo;
import jym.tan.tmdb.bean.PersonInfo;
import jym.tan.tmdb.bean.SessionID;
import jym.tan.tmdb.bean.wrapper.MovieAlternativeTitleWrapper;
import jym.tan.tmdb.bean.wrapper.MovieCastWrapper;
import jym.tan.tmdb.bean.wrapper.MovieImageWrapper;
import jym.tan.tmdb.bean.wrapper.MovieKeywordWrapper;
import jym.tan.tmdb.bean.wrapper.MovieReleaseWrapper;
import jym.tan.tmdb.bean.wrapper.MovieSearchWrapper;
import jym.tan.tmdb.bean.wrapper.MovieTrailerWrapper;
import jym.tan.tmdb.bean.wrapper.MovieTranslationWrapper;
import jym.tan.tmdb.bean.wrapper.PersonCreditWrapper;
import jym.tan.tmdb.bean.wrapper.PersonImageWrapper;
import jym.tan.tmdb.bean.wrapper.PersonSearchWrapper;
import jym.tan.tmdb.constant.TMDBConstants;
import jym.tan.tmdb.method.auth.AuthenticationRequestToken;
import jym.tan.tmdb.method.auth.AuthenticationSessionID;
import jym.tan.tmdb.method.get.LatestMovie;
import jym.tan.tmdb.method.get.MovieAlternativeTitles;
import jym.tan.tmdb.method.get.MovieCasts;
import jym.tan.tmdb.method.get.MovieImages;
import jym.tan.tmdb.method.get.MovieKeywords;
import jym.tan.tmdb.method.get.MovieReleaseInfo;
import jym.tan.tmdb.method.get.MovieTrailers;
import jym.tan.tmdb.method.get.MovieTranslations;
import jym.tan.tmdb.method.get.PersonCredits;
import jym.tan.tmdb.method.get.PersonImages;
import jym.tan.tmdb.method.get.SearchMovies;
import jym.tan.tmdb.method.get.SearchPeople;
import jym.tan.tmdb.web.Browser;

/**
 * The class <code>TMDB</code> is used to manipulate the TMDb API 3.
 * <p>
 * 	For more information see <a href="http://help.themoviedb.org/kb/api/about-3">About 3</a>.
 * </p>
 * It is a singleton class. To get an instance of this class you should invoke 
 * the {@link #getInstance(String)} method with a valid TheMovieDb API key.
 * 
 * @author Tanmoy
 *
 */
public class TMDB {

	private static final Object OBJECT_LOCK = new Object();
	
	private static TMDB tmdb;	
	private Browser browser = Browser.getBrowser();
	private String key;
	
	private SearchMovies searchMovies = new SearchMovies(this);
	private jym.tan.tmdb.method.get.MovieInfo movieInfo = new jym.tan.tmdb.method.get.MovieInfo(this);
	private MovieAlternativeTitles movieAlternativeTitles = new MovieAlternativeTitles(this);
	private MovieCasts movieCasts = new MovieCasts(this);
	private MovieImages movieImages = new MovieImages(this);
	private MovieKeywords movieKeywords = new MovieKeywords(this);
	private MovieReleaseInfo movieReleaseInfo = new MovieReleaseInfo(this);
	private MovieTrailers movieTrailers = new MovieTrailers(this);
	private MovieTranslations movieTranslations = new MovieTranslations(this);
	private SearchPeople searchPeople = new SearchPeople(this);
	private jym.tan.tmdb.method.get.PersonInfo personInfo = new jym.tan.tmdb.method.get.PersonInfo(this);
	private PersonCredits personCredits = new PersonCredits(this);
	private PersonImages personImages = new PersonImages(this);
	private LatestMovie latestMovie = new LatestMovie(this);
	private jym.tan.tmdb.method.get.Configuration configuration = new jym.tan.tmdb.method.get.Configuration(this);
	private AuthenticationRequestToken authenticationRequestToken = new AuthenticationRequestToken(this);
	private AuthenticationSessionID authenticationSessionID = new AuthenticationSessionID(this);
	/**
	 * Don't let anyone else instantiate this class.
	 */
	private TMDB(String key) {
		this.key = key;
	}
	
	/**
	 * Returns the TheMovieDb API Key.
	 * @return
	 * 		The key
	 */
	public String getKey() {
		return key;
	}
	
	/**
	 * Get an instance of <code>TMDB</code> class.
	 * @param key
	 * 		The TheMovieDb API key
	 * @return 
	 * 		The <code>TMDB</code> object
	 */
	public static final TMDB getInstance(String key) {
		if(tmdb == null) {
			synchronized (OBJECT_LOCK) {
				tmdb = new TMDB(key);
			}
		}
		return tmdb;
	}
	
	public Browser getBrowser(){
		return browser;
	}
	
	/**
	 * This method set the 
	 * <ul>
	 * 	<li>Connection Timeout</li>
	 * 	<li>Read Timeout</li> 
	 * </ul>
	 * values to the internal browser used by TMDB
	 * @param connect
	 * 		The connection timeout 
	 * @param read
	 * 		The read timeout
	 */
	public void setTimeout(int connect, int read) {
        browser.setWebTimeoutConnect(connect);
        browser.setWebTimeoutRead(read);
    }

	/**
	 * This method set the 
	 * <ul>
	 * 	<li>Host - The Proxy Host</li>
	 * 	<li>Port - The Proxy Password</li> 
	 * 	<li>Username - The Username if available</li>
	 * 	<li>Password - The Password if available</li> 
	 * </ul>
	 * values to the internal browser used by TMDB
	 * @param host
	 * 		The Proxy Host
	 * @param port
	 * 		The Proxy Password
	 * @param username
	 * 		The Username
	 * @param password
	 * 		The Password
	 */
	public void setProxy(String host, String port, String username, String password) {
		browser.setProxyHost(host);
		browser.setProxyPort(port);
		browser.setProxyUsername(username);
		browser.setProxyPassword(password);
    }
	
	/**
	 * Returns a {@link MovieSearchWrapper} object containing the 
	 * search information associated with the movie name given to it.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/search-movies">Search Movies</a>.
	 * </p>
	 * @param movieName 
	 * 		The name of the movie to be searched 
	 * @return
	 * 		The <code>MovieSearchWrapper</code> object
	 */
	public MovieSearchWrapper searchMovies(String movieName) {
		return searchMovies(movieName, TMDBConstants.BLANK);
	}
	
	/**
	 * Returns a {@link MovieSearchWrapper} object containing the 
	 * search information associated with the movie name given to it.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/search-movies">Search Movies</a>.
	 * </p>
	 * @param movieName 
	 * 		The name of the movie to be searched 
	 * @param year 
	 * 		The movie released year to narrow the search results
	 * @return
	 * 		The <code>MovieSearchWrapper</code> object
	 */
	public MovieSearchWrapper searchMovies(String movieName, String year) {
		return searchMovies(movieName, year, TMDBConstants.ONE);
	}
	
	/**
	 * Returns a {@link MovieSearchWrapper} object containing the 
	 * search information associated with the movie name given to it.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/search-movies">Search Movies</a>.
	 * </p>
	 * @param movieName 
	 * 		The name of the movie to be searched 
	 * @param page 
	 * 		Some searches will have more than 20 results, the default 
	 * 		number of items returned per page. To iterate through use the page parameter
	 * @return
	 * 		The <code>MovieSearchWrapper</code> object
	 */
	public MovieSearchWrapper searchMovies(String movieName, int page) {
		return searchMovies(movieName, TMDBConstants.BLANK, page);
	}
	
	/**
	 * Returns a {@link MovieSearchWrapper} object containing the 
	 * search information associated with the movie name given to it.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/search-movies">Search Movies</a>.
	 * </p>
	 * @param movieName 
	 * 		The name of the movie to be searched 
	 * @param inculdeAdult 
	 * 		You can toggle whether or not to include adult items in 
	 * 		your search by using this parameter. The expected value is either true or false
	 * 		When it is not specified, it is set to false.
	 * @return
	 * 		The <code>MovieSearchWrapper</code> object
	 */
	public MovieSearchWrapper searchMovies(String movieName, boolean inculdeAdult) {
		return searchMovies(movieName, TMDBConstants.BLANK, TMDBConstants.ONE, false, TMDBConstants.BLANK, inculdeAdult);
	}
	
	/**
	 * Returns a {@link MovieSearchWrapper} object containing the 
	 * search information associated with the movie name given to it.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/search-movies">Search Movies</a>.
	 * </p>
	 * @param movieName 
	 * 		The name of the movie to be searched 
	 * @param year 
	 * 		The movie released year to narrow the search results
	 * @param page  
	 * 		Some searches will have more than 20 results, the default 
	 * 		number of items returned per page. To iterate through use the page parameter
	 * @return
	 * 		The <code>MovieSearchWrapper</code> object
	 */
	public MovieSearchWrapper searchMovies(String movieName, String year, int page) {
		return searchMovies(movieName, year, page, TMDBConstants.BLANK);
	}	
		
	/**
	 * Returns a {@link MovieSearchWrapper} object containing the 
	 * search information associated with the movie name given to it.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/search-movies">Search Movies</a>.
	 * </p>
	 * @param movieName 
	 * 		The name of the movie to be searched 
	 * @param allResults 
	 * 		Some searches will have more than 20 results. So the value 
	 * 		of <code>allResults</code> toggle whether or not the <code>MovieSearchWrapper</code> 
	 * 		object contains all search results 
	 * @param inculdeAdult 
	 * 		You can toggle whether or not to include adult items in 
	 * 		your search by using this parameter. The expected value is either true or false
	 * @return
	 * 		The <code>MovieSearchWrapper</code> object
	 */
	public MovieSearchWrapper searchMovies(String movieName, boolean allResults, boolean inculdeAdult) {
		return searchMovies(movieName, TMDBConstants.BLANK, TMDBConstants.ONE, allResults, TMDBConstants.BLANK, inculdeAdult);
	}
	
	/**
	 * Returns a {@link MovieSearchWrapper} object containing the 
	 * search information associated with the movie name given to it.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/search-movies">Search Movies</a>.
	 * </p>
	 * @param movieName 
	 * 		The name of the movie to be searched 
	 * @param year 
	 * 		The movie released year to narrow the search results
	 * @param allResults 
	 * 		Some searches will have more than 20 results. So the value 
	 * 		of <code>allResults</code> toggle whether or not the <code>MovieSearchWrapper</code> 
	 * 		object contains all search results 
	 * @return
	 * 		The <code>MovieSearchWrapper</code> object
	 */
	public MovieSearchWrapper searchMovies(String movieName, String year, boolean allResults) {
		return searchMovies(movieName, year, TMDBConstants.ONE, allResults, TMDBConstants.BLANK, TMDBConstants.FALSE);
	}
	
	/**
	 * Returns a {@link MovieSearchWrapper} object containing the 
	 * search information associated with the movie name given to it.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/search-movies">Search Movies</a>.
	 * </p>
	 * @param movieName 
	 * 		The name of the movie to be searched 
	 * @param year 
	 * 		The movie released year to narrow the search results
	 * @param page 
	 * 		Some searches will have more than 20 results, the default 
	 * 		number of items returned per page. To iterate through use the page parameter
	 * @param language 
	 * 		The language parameter tries to localize the movie data we return. If the 
	 * 		language being requested does not exist, the value will be left blank
	 * 		The expected value is a ISO 639-1 code
	 * @return
	 * 		The <code>MovieSearchWrapper</code> object
	 */
	public MovieSearchWrapper searchMovies(String movieName, String year, int page, String language) {
		return searchMovies(movieName, year, page, TMDBConstants.FALSE, language, TMDBConstants.FALSE);
	}	
	
	/**
	 * Returns a {@link MovieSearchWrapper} object containing the 
	 * search information associated with the movie name given to it.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/search-movies">Search Movies</a>.
	 * </p>
	 * @param movieName 
	 * 		The name of the movie to be searched 
	 * @param year 
	 * 		The movie released year to narrow the search results
	 * @param allResults 
	 * 		Some searches will have more than 20 results. So the value 
	 * 		of <code>allResults</code> toggle whether or not the <code>MovieSearchWrapper</code> 
	 * 		object contains all search results 
	 * @param inculdeAdult 
	 * 		You can toggle whether or not to include adult items in 
	 * 		your search by using this parameter. The expected value is either true or false
	 * @return
	 * 		The <code>MovieSearchWrapper</code> object
	 */
	public MovieSearchWrapper searchMovies(String movieName, String year, boolean allResults, boolean inculdeAdult) {
		return searchMovies(movieName, year, TMDBConstants.ONE, allResults, TMDBConstants.BLANK, inculdeAdult);
	}
	
	/**
	 * Returns a {@link MovieSearchWrapper} object containing the 
	 * search information associated with the movie name given to it.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/search-movies">Search Movies</a>.
	 * </p>
	 * @param movieName 
	 * 		The name of the movie to be searched 
	 * @param year 
	 * 		The movie released year to narrow the search results
	 * @param allResults 
	 * 		Some searches will have more than 20 results. So the value 
	 * 		of <code>allResults</code> toggle whether or not the <code>MovieSearchWrapper</code> 
	 * 		object contains all search results 
	 * @param language 
	 * 		The language parameter tries to localize the movie data we return. If the 
	 * 		language being requested does not exist, the value will be left blank. 
	 * 		The expected value is a ISO 639-1 code
	 * @return
	 * 		The <code>MovieSearchWrapper</code> object
	 */
	public MovieSearchWrapper searchMovies(String movieName, String year, boolean allResults, String language) {
		return searchMovies(movieName, year, TMDBConstants.ONE, allResults, language, TMDBConstants.FALSE);
	}
	
	/**
	 * Returns a {@link MovieSearchWrapper} object containing the 
	 * search information associated with the movie name given to it.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/search-movies">Search Movies</a>.
	 * </p>
	 * @param movieName 
	 * 		The name of the movie to be searched 
	 * @param year 
	 * 		The movie released year to narrow the search results
	 * @param allResults 
	 * 		Some searches will have more than 20 results. So the value 
	 * 		of <code>allResults</code> toggle whether or not the <code>MovieSearchWrapper</code> 
	 * 		object contains all search results 
	 * @param language 
	 * 		The language parameter tries to localize the movie data we return. If the 
	 * 		language being requested does not exist, the value will be left blank. 
	 * 		The expected value is a ISO 639-1 code
	 * @param inculdeAdult 
	 * 		You can toggle whether or not to include adult items in 
	 * 		your search by using this parameter. The expected value is either true or false
	 * @return
	 * 		The <code>MovieSearchWrapper</code> object
	 */
	public MovieSearchWrapper searchMovies(String movieName, String year, boolean allResults, String language, boolean inculdeAdult) {
		return searchMovies(movieName, year, TMDBConstants.ONE, allResults, language, inculdeAdult);
	}
	
	/**
	 * Returns a {@link MovieSearchWrapper} object containing the 
	 * search information associated with the movie name given to it.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/search-movies">Search Movies</a>.
	 * </p>
	 * @param movieName 
	 * 		The name of the movie to be searched 
	 * @param year 
	 * 		The movie released year to narrow the search results
	 * @param page 
	 * 		Some searches will have more than 20 results, the default 
	 * 		number of items returned per page. To iterate through use the page parameter
	 * @param allResults 
	 * 		Some searches will have more than 20 results. So the value 
	 * 		of <code>allResults</code> toggle whether or not the <code>MovieSearchWrapper</code> 
	 * 		object contains all search results 
	 * @param language 
	 * 		The language parameter tries to localize the movie data we return. If the 
	 * 		language being requested does not exist, the value will be left blank. 
	 * 		The expected value is a ISO 639-1 code
	 * @param inculdeAdult 
	 * 		You can toggle whether or not to include adult items in 
	 * 		your search by using this parameter. The expected value is either true or false
	 * @return
	 * 		The <code>MovieSearchWrapper</code> object
	 */
	public MovieSearchWrapper searchMovies(String movieName, String year, int page, boolean allResults, String language, boolean inculdeAdult) {		
		try {
			return searchMovies.search(movieName, year, page, allResults, language, inculdeAdult);
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * Returns a {@link MovieInfo} object containing the movie information searched for.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-info">Movie Info</a>.
	 * </p>
	 * @param movieId 
	 * 		The TMDB id
	 * @return 
	 * 		The <code>MovieInfo</code> object
	 */
	public MovieInfo getMovieInfo(int movieId) {
		return getMovieInfo(movieId, TMDBConstants.BLANK);
	}
	
	/**
	 * Returns a {@link MovieInfo} object containing the movie information searched for.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-info">Movie Info</a>.
	 * </p>
	 * @param imdbId 
	 * 		The IMDB id
	 * @return 
	 * 		The <code>MovieInfo</code> object 
	 */
	public MovieInfo getMovieInfo(String imdbId) {
		return getMovieInfo(String.valueOf(imdbId), TMDBConstants.BLANK);
	}
	
	/**
	 * Returns a {@link MovieInfo} object containing the movie information searched for.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-info">Movie Info</a>.
	 * </p>
	 * @param movieId 
	 * 		The TMDB id
	 * @param language 
	 * 		The language parameter tries to localize the movie data we return. If the 
	 * 		language being requested does not exist, the value will be left blank. 
	 * 		The expected value is a ISO 639-1 code
	 * @return 
	 * 		The <code>MovieInfo</code> object 
	 */
	public MovieInfo getMovieInfo(int movieId, String language) {	
		return getMovieInfo(String.valueOf(movieId), language);	
	}
	
	/**
	 * Returns a {@link MovieInfo} object containing the movie information searched for.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-info">Movie Info</a>.
	 * </p>
	 * @param movieId 
	 * 		The TMDB id/ the IMDB id
	 * @param language 
	 * 		The language parameter tries to localize the movie data we return. If the 
	 * 		language being requested does not exist, the value will be left blank. 
	 * 		The expected value is a ISO 639-1 code
	 * @return 
	 * 		The <code>MovieInfo</code> object 
	 */
	public MovieInfo getMovieInfo(String movieId, String language) {
		try {
			return movieInfo.getMovieInfo(movieId, language);
		} catch (Exception e) {
			return null;
		}		
	}
	
	/**
	 * Returns a {@link MovieAlternativeTitleWrapper} object containing the information of the 
	 * alternative titles of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-alternative-titles">Movie Alternative Titles</a>.
	 * </p>
	 * @param movieId
	 * 		The TMDB id
	 * @return
	 * 		The <code>MovieAlternativeTitleWrapper</code> object
	 */
	public MovieAlternativeTitleWrapper getMovieAlternativeTitles(int movieId) {
		return getMovieAlternativeTitles(movieId, TMDBConstants.BLANK);
	}
	
	/**
	 * Returns a {@link MovieAlternativeTitleWrapper} object containing the information of the 
	 * alternative titles of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-alternative-titles">Movie Alternative Titles</a>.
	 * </p>
	 * @param imdbId
	 * 		The IMDB id
	 * @return
	 * 		The <code>MovieAlternativeTitleWrapper</code> object
	 */
	public MovieAlternativeTitleWrapper getMovieAlternativeTitles(String imdbId) {
		return getMovieAlternativeTitles(imdbId, TMDBConstants.BLANK);
	}
	
	/**
	 * Returns a {@link MovieAlternativeTitleWrapper} object containing the information of the 
	 * alternative titles of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-alternative-titles">Movie Alternative Titles</a>.
	 * </p>
	 * @param movieId
	 * 		The TMDB id
	 * @param country
	 * 		The country parameter will filter the results to only include titles in that 
	 * 		particular country. Remember, if a translation exists, it might not have an 
	 * 		entry here. The expected value is a ISO 3166-1 code
	 * @return
	 * 		The <code>MovieAlternativeTitleWrapper</code> object
	 */
	public MovieAlternativeTitleWrapper getMovieAlternativeTitles(int movieId, String country) {
		return getMovieAlternativeTitles(String.valueOf(movieId), country);
	}
	
	/**
	 * Returns a {@link MovieAlternativeTitleWrapper} object containing the information of the 
	 * alternative titles of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-alternative-titles">Movie Alternative Titles</a>.
	 * </p>
	 * @param movieId
	 * 		The TMDB id/ the IMDB id
	 * @param country
	 * 		The country parameter will filter the results to only include titles in that 
	 * 		particular country. Remember, if a translation exists, it might not have an 
	 * 		entry here. The expected value is a ISO 3166-1 code
	 * @return
	 * 		The <code>MovieAlternativeTitleWrapper</code> object
	 */
	public MovieAlternativeTitleWrapper getMovieAlternativeTitles(String movieId, String country) {
		try {
			return movieAlternativeTitles.getAlternativeTitleWrapper(movieId, country);
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * Returns a {@link MovieCastWrapper} object containing the information of the 
	 * cast and crew of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-casts">Movie Casts</a>.
	 * </p> 
	 * @param movieId
	 * 		The TMDB id
	 * @return 		
	 * 		The <code>MovieCastWrapper</code> object
	 */
	public MovieCastWrapper getMovieCasts(int movieId) {
		return getMovieCasts(String.valueOf(movieId));
	}
	
	/**
	 * Returns a {@link MovieCastWrapper} object containing the information of the 
	 * cast and crew of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-casts">Movie Casts</a>.
	 * </p> 
	 * @param movieId
	 * 		The TMDB id/ the IMDB id
	 * @return 		
	 * 		The <code>MovieCastWrapper</code> object
	 */
	public MovieCastWrapper getMovieCasts(String movieId) {
		try {
			return movieCasts.getMovieCastWrapper(movieId);
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * Returns a {@link MovieImageWrapper} object containing the information of the 
	 * images of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-images">Movie Images</a>.
	 * </p> 
	 * @param movieId
	 * 		The TMDB id
	 * @return 		
	 * 		The <code>MovieImageWrapper</code> object
	 */
	public MovieImageWrapper getMovieImages(int movieId) {
		return getMovieImages(String.valueOf(movieId));
	}
	
	/**
	 * Returns a {@link MovieImageWrapper} object containing the information of the 
	 * images of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-images">Movie Images</a>.
	 * </p> 
	 * @param tmdbId
	 * 		The IMDB id
	 * @return 		
	 * 		The <code>MovieImageWrapper</code> object
	 */
	public MovieImageWrapper getMovieImages(String tmdbId) {
		return getMovieImages(tmdbId, TMDBConstants.BLANK);
	}
	
	/**
	 * Returns a {@link MovieImageWrapper} object containing the information of the 
	 * images of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-images">Movie Images</a>.
	 * </p> 
	 * @param movieId
	 * 		The TMDB id
	 * @param language
	 * 		The language parameter tries to localize the movie data we return. If the 
	 * 		language being requested does not exist, the value will be left blank. 
	 * 		The expected value is a ISO 639-1 code
	 * @return 		
	 * 		The <code>MovieImageWrapper</code> object
	 */
	public MovieImageWrapper getMovieImages(int movieId, String language) {
		return getMovieImages(String.valueOf(movieId), language);
	}
	
	/**
	 * Returns a {@link MovieImageWrapper} object containing the information of the 
	 * images of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-images">Movie Images</a>.
	 * </p> 
	 * @param movieId
	 * 		The TMDB id/ the IMDB id
	 * @param language
	 * 		The language parameter tries to localize the movie data we return. If the 
	 * 		language being requested does not exist, the value will be left blank. 
	 * 		The expected value is a ISO 639-1 code
	 * @return 		
	 * 		The <code>MovieImageWrapper</code> object
	 */
	public MovieImageWrapper getMovieImages(String movieId, String language) {
		try {
			return movieImages.getMovieImageWrapper(movieId, language);
		} catch (Exception e) {
			return null;
		}
	}	
	
	/**
	 * Returns a {@link MovieKeywordWrapper} object containing the information of the 
	 * keywords of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-keywords">Movie Keywords</a>.
	 * </p> 
	 * @param movieId
	 * 		The TMDB id
	 * @return	
	 * 		The <code>MovieKeywordWrapper</code> object
	 */
	public MovieKeywordWrapper getMovieKeywords(int movieId) {
		return getMovieKeywords(String.valueOf(movieId));
	}
	
	/**
	 * Returns a {@link MovieKeywordWrapper} object containing the information of the 
	 * keywords of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-keywords">Movie Keywords</a>.
	 * </p> 
	 * @param movieId
	 * 		The TMDB id/ the IMDB id
	 * @return	
	 * 		The <code>MovieKeywordWrapper</code> object
	 */
	public MovieKeywordWrapper getMovieKeywords(String movieId) {
		try {
			return movieKeywords.getMovieKeywordWrapper(movieId);
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * Returns a {@link MovieReleaseWrapper} object containing the information of the 
	 * releases of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-release-info">Movie Release Info</a>.
	 * </p> 
	 * @param movieId
	 * 		The TMDB id
	 * @return	
	 * 		The <code>MovieReleaseWrapper</code> object
	 */
	public MovieReleaseWrapper getMovieReleaseInfo(int movieId) { 
		return getMovieReleaseInfo(String.valueOf(movieId));
	}
	
	/**
	 * Returns a {@link MovieReleaseWrapper} object containing the information of the 
	 * releases of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-release-info">Movie Release Info</a>.
	 * </p> 
	 * @param movieId
	 * 		The TMDB id/ the IMDB id
	 * @return	
	 * 		The <code>MovieReleaseWrapper</code> object
	 */
	public MovieReleaseWrapper getMovieReleaseInfo(String movieId) {
		try {
			return movieReleaseInfo.getMovieReleaseWrapper(movieId);
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * Returns a {@link MovieTrailerWrapper} object containing the information of the 
	 * trailers of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-trailers">Movie Trailers</a>.
	 * </p> 
	 * @param movieId
	 * 		The TMDB id
	 * @return
	 * 		The <code>MovieTrailerWrapper</code> object
	 */
	public MovieTrailerWrapper getMovieTrailers(int movieId) {
		return getMovieTrailers(String.valueOf(movieId));
	}
	
	/**
	 * Returns a {@link MovieTrailerWrapper} object containing the information of the 
	 * trailers of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-trailers">Movie Trailers</a>.
	 * </p> 
	 * @param movieId
	 * 		The TMDB id/ the IMDB id
	 * @return
	 * 		The <code>MovieTrailerWrapper</code> object
	 */
	public MovieTrailerWrapper getMovieTrailers(String movieId) {
		return getMovieTrailers(movieId, TMDBConstants.BLANK);
	}
	
	/**
	 * Returns a {@link MovieTrailerWrapper} object containing the information of the 
	 * trailers of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-trailers">Movie Trailers</a>.
	 * </p> 
	 * @param movieId
	 * 		The TMDB id
	 * @param language
	 * 		The language parameter tries to localize the movie data we return. If the 
	 * 		language being requested does not exist, the value will be left blank. 
	 * 		The expected value is a ISO 639-1 code
	 * @return
	 * 		The <code>MovieTrailerWrapper</code> object
	 */
	public MovieTrailerWrapper getMovieTrailers(int movieId, String language) {
		return getMovieTrailers(String.valueOf(movieId), language);
	}
	
	/**
	 * Returns a {@link MovieTrailerWrapper} object containing the information of the 
	 * trailers of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-trailers">Movie Trailers</a>.
	 * </p> 
	 * @param movieId
	 * 		The TMDB id/ the IMDB id
	 * @param language
	 * 		The language parameter tries to localize the movie data we return. If the 
	 * 		language being requested does not exist, the value will be left blank. 
	 * 		The expected value is a ISO 639-1 code
	 * @return
	 * 		The <code>MovieTrailerWrapper</code> object
	 */
	public MovieTrailerWrapper getMovieTrailers(String movieId, String language) {
		try {
			return movieTrailers.getMovieTrailerWrapper(movieId, language);
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * Returns a {@link MovieTranslationWrapper} object containing the information of the 
	 * translations of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-translations">Movie Translations</a>.
	 * </p> 
	 * @param movieId
	 * 		The TMDB id
	 * @return
	 * 		The <code>MovieTranslationWrapper</code> object
	 */
	public MovieTranslationWrapper getMovieTranslations(int movieId) {
		return getMovieTranslations(String.valueOf(movieId));
	}
	
	/**
	 * Returns a {@link MovieTranslationWrapper} object containing the information of the 
	 * translations of a given movie.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-translations">Movie Translations</a>.
	 * </p> 
	 * @param movieId
	 * 		The TMDB id/ the IMDB id
	 * @return
	 * 		The <code>MovieTranslationWrapper</code> object
	 */
	public MovieTranslationWrapper getMovieTranslations(String movieId) {
		try {
			return movieTranslations.getMovieTranslationWrapper(movieId);
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * Returns a {@link PersonSearchWrapper} object containing the 
	 * search information associated with the person name given to it.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/search-people">Search People</a>.
	 * </p> 
	 * @param personName
	 * 		The person name - the query param is your search text. It works best when the text has been 
	 * 		properly escaped.
	 * @return
	 * 		The <code>PersonSearchWrapper</code> object
	 */
	public PersonSearchWrapper searchPeople(String personName) {
		return searchPeople(personName, TMDBConstants.ONE, TMDBConstants.FALSE);
	}
	
	/**
	 * Returns a {@link PersonSearchWrapper} object containing the 
	 * search information associated with the person name given to it.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/search-people">Search People</a>.
	 * </p> 
	 * @param personName
	 * 		The person name - the query param is your search text. It works best when the text has been 
	 * 		properly escaped.
	 * @param page 
	 * 		Some searches will have more than 20 results, the default 
	 * 		number of items returned per page. To iterate through use the page parameter
	 * @return
	 * 		The <code>PersonSearchWrapper</code> object
	 */
	public PersonSearchWrapper searchPeople(String personName, int page) {
		return searchPeople(personName, page, TMDBConstants.FALSE);
	}
	
	/**
	 * Returns a {@link PersonSearchWrapper} object containing the 
	 * search information associated with the person name given to it.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/search-people">Search People</a>.
	 * </p> 
	 * @param personName
	 * 		The person name - the query param is your search text. It works best when the text has been 
	 * 		properly escaped.
	 * @param allResults 
	 * 		Some searches will have more than 20 results. So the value 
	 * 		of <code>allResults</code> toggle whether or not the <code>MovieSearchWrapper</code> 
	 * 		object contains all search results 
	 * @return
	 * 		The <code>PersonSearchWrapper</code> object
	 */
	public PersonSearchWrapper searchPeople(String personName, boolean allResults) {
		return searchPeople(personName, TMDBConstants.ONE, allResults);		
	}
	
	/**
	 * Returns a {@link PersonSearchWrapper} object containing the 
	 * search information associated with the person name given to it.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/search-people">Search People</a>.
	 * </p> 
	 * @param personName
	 * 		The person name - the query param is your search text. It works best when the text has been 
	 * 		properly escaped.
	 * @param page 
	 * 		Some searches will have more than 20 results, the default 
	 * 		number of items returned per page. To iterate through use the page parameter
	 * @param allResults 
	 * 		Some searches will have more than 20 results. So the value 
	 * 		of <code>allResults</code> toggle whether or not the <code>MovieSearchWrapper</code> 
	 * 		object contains all search results 
	 * @return
	 * 		The <code>PersonSearchWrapper</code> object
	 */
	public PersonSearchWrapper searchPeople(String personName, int page, boolean allResults) {
		try {
			return searchPeople.search(personName, page, allResults);
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * Returns a {@link PersonInfo} object containing the person information searched for.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/person-info">Person Info</a>.
	 * </p>
	 * @param personId
	 * 		The Person id
	 * @return
	 * 		The <code>PersonInfo</code> object
	 */
	public PersonInfo getPersonInfo(int personId) {
		try {
			return personInfo.getPersonInfo(String.valueOf(personId));
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * Returns a {@link PersonCreditWrapper} object containing the information of the 
	 * credits of a given person.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/person-credits">Person Credits</a>.
	 * </p>
	 * @param personId
	 * 		The Person id
	 * @return
	 * 		The <code>PersonCreditWrapper</code> object
	 */
	public PersonCreditWrapper getPersonCredits(int personId) {
		return getPersonCredits(personId, TMDBConstants.BLANK);
	}
	
	/**
	 * Returns a {@link PersonCreditWrapper} object containing the information of the 
	 * credits of a given person.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/person-credits">Person Credits</a>.
	 * </p>
	 * @param personId
	 * 		The Person id
	 * @param language
	 * 		The language parameter tries to localize the movie data we return. If the 
	 * 		language being requested does not exist, the value will be left blank. 
	 * 		The expected value is a ISO 639-1 code
	 * @return
	 * 		The <code>PersonCreditWrapper</code> object
	 */
	public PersonCreditWrapper getPersonCredits(int personId, String language) {
		try {
			return personCredits.getPersonCreditWrapper(personId, language);
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * Returns a {@link PersonImageWrapper} object containing the information of the 
	 * images of a given person.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/person-images">Person Images</a>.
	 * </p>
	 * @param personId
	 * 		The Person id
	 * @return
	 * 		The <code>PersonImageWrapper</code> object
	 */
	public PersonImageWrapper getPersonImages(int personId){
		try {
			return personImages.getPersonImageWrapper(personId);
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * Returns a {@link MovieInfo} object containing the information of the 
	 * latest movie added in TMDb.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/movie-info">Movie Info</a>.
	 * </p>
	 * @return
	 * 		The <code>MovieInfo</code> object
	 */
	public MovieInfo getLatestMovie() {		
		try {
			return latestMovie.getMovieInfo();
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * Returns a {@link Configuration} object containing the information of the 
	 * configuration data. Some elements of the API require some knowledge of 
	 * the configuration data which can be found here.
	 * <p>
	 * 	For more information see <a href="http://help.themoviedb.org/kb/api/configuration">Configuration</a>.
	 * </p>
	 * @return
	 * 		The <code>Configuration</code> object
	 */
	public Configuration getConfiguration() {
		try {
			return configuration.getConfiguration();
		} catch (Exception e) {
			return null;
		}
	}
	
	public AuthenticationRequest getAuthenticationRequest() {
		try {
			return authenticationRequestToken.getAuthenticationRequest();
		} catch (Exception e) {
			return null;
		}
	}
	
	public SessionID getSessionID(String requestToken) {
		try {
			return authenticationSessionID.getSessionID(requestToken);
		} catch (Exception e) {
			return null;
		}
	}
}